package com.yishun.springboot.service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.yishun.springboot.pojo.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.StringUtils;

import com.RequestGongWuShu.CWRService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yishun.springboot.mapper.GwsAccessDeviceDTOMapper;
import com.yishun.springboot.mapper.GwsCWRMapper;
import com.yishun.springboot.mapper.GwsPeopleInfoDTOMapper;
import com.yishun.springboot.mapper.GwsPersonMapper;
import com.yishun.springboot.mapper.GwsTeamDTOMapper;
import com.yishun.springboot.mapper.GwsYfRealNameSystemPushMapper;
import com.yishun.springboot.mapper.YfPeopleInfoMapper;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@Component
//@SpringBootTest
//@RunWith(SpringRunner.class)
public class GwsYfRealNameSystemPushService {

    @Autowired
    GwsYfRealNameSystemPushMapper realNameSystemPushMapper;

    // 班组
    @Autowired
    GwsTeamDTOMapper gwsTeamDTOMapper;

    // 人员信息
    @Autowired
    GwsPeopleInfoDTOMapper gwsPeopleInfoDTOMapper;

    // 工务署业务服务类
    @Autowired
    InnerFormalGWSCWRService innerFormalGWSCWRService;

    @Autowired
    GwsCWRMapper gwsCWRMapper;

    @Autowired
    GwsPersonMapper gwsPersonMapper;

    @Autowired
    GongWuSuUploadCWSService gongWuSuUploadCWSService;

    @Autowired
    GwsAccessDeviceDTOMapper gwsAccessDeviceDTOMapper;

    @Autowired
    YfPeopleInfoMapper yfPeopleInfoMapper;

    /**
     * 宇泛平台设备直连，推送班组信息到工务署平台
     */
    @Async(value = "asyncExecutor")
    @Scheduled(fixedDelay = 1000 * 60)
    public void uploadGwsTeam() {
        log.info("宇泛设备直连，推送工务署班组开始..........");

        List<GwsYfRealNameSystemPush> pushs = realNameSystemPushMapper.findAll();

        // 用来存储单个实名制信息
        GwsYfRealNameSystemPush push = new GwsYfRealNameSystemPush();

        // 存储单个班组信息
        GwsTeamDTO dto = new GwsTeamDTO();

        // 用来存储工务署地址
        String gwsProjectCode = "";

        // 用来存储所有该项目所有班组
        List<GwsTeamDTO> dtos = new ArrayList<GwsTeamDTO>();

        // 成功数量
        int counter = 0;

        // 开始时间
        long beginTime = System.currentTimeMillis();

        for (int i = 0; i < pushs.size(); i++) {
            push = pushs.get(i);
            // 判断数据状态是否是需要推送
            if (push.getPushDataTeam() == null || !push.getPushDataTeam()) {
                continue;
            }
            // 通过宇泛应用Id去查询班组信息
            String projectGuid = push.getProjectGuid();

            dtos = gwsTeamDTOMapper.findByProjectGuid(projectGuid);

            for (int j = 0; j < dtos.size(); j++) {
                dto = dtos.get(j);
                // 将工程编号插入进去，因为数据库没有，在转换成json
                gwsProjectCode = push.getGwsProjectCode();
                dto.setProject_ID(gwsProjectCode);

                JSONObject paramJson = JSONObject.parseObject(JSON.toJSONString(dto));

                String timestamp = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");

                String resultInfo = innerFormalGWSCWRService.addTeam(paramJson, push.getApiSecret(), push.getApiKey(),
                        push.getApiVersion(), push.getClientSerial(), timestamp);

                String resultCode = innerFormalGWSCWRService.parseResultsCode(resultInfo);

                String resultMessage = innerFormalGWSCWRService.parseResultsMessage(resultInfo);

                if (resultMessage.equals("成功") && resultCode.equals("00")) {
                    String tableTeamId = JSONObject.parseObject(innerFormalGWSCWRService.parseResultsData(resultInfo))
                            .getString("team_id");
                    String tableTeamName = JSONObject.parseObject(innerFormalGWSCWRService.parseResultsData(resultInfo))
                            .getString("team_name");
                    int res = gwsCWRMapper.innerOneTeamRecord(gwsProjectCode, tableTeamId, tableTeamName,
                            dto.getEmp_company(), dto.getSUID());
                    if (res < 1) {
                        log.error(dto.getEmp_company() + "-" + dto.getTeam_name() + "-推送班组成功，但是新增数据库失败");
                        continue;
                    }
                    counter++;
                } else {
                    log.error(dto.getEmp_company() + "-" + dto.getTeam_name() + "-推送失败,原因:" + resultMessage);
                    continue;
                }
            }
        }

        long timeSpent = System.currentTimeMillis() - beginTime;
        log.info("推送班组结束，本次推送耗时" + timeSpent + "---成功/总数：" + counter + "/" + dtos.size());
    }

    /**
     * 人员信息
     */
    @Async(value = "asyncExecutor")
    @Scheduled(fixedDelay = 1000 * 60)
//    @Test
    public void updatePropleInfo() {

        log.info("宇泛设备直连，推送工务署人员开始..........");

        List<GwsYfRealNameSystemPush> pushs = realNameSystemPushMapper.findAll();

        // 用来存储单个实名制信息
        GwsYfRealNameSystemPush push = new GwsYfRealNameSystemPush();

        String gwsProjectCode = "";

        String projectGuid = "";

        List<GwsPeopleInfoDTO> infoDTOs = new ArrayList<GwsPeopleInfoDTO>();

        GwsPeopleInfoDTO infoDTO = new GwsPeopleInfoDTO();

        List<Object> failPeople = new ArrayList<Object>();

        // 存储工务署需要的文件ID
        GwsPerson gwsPerson = new GwsPerson();

        StringBuffer idCode = null;

        int counter = 0;

        // 开始时间
        long beginTime = System.currentTimeMillis();

        // 循环需要推送的项目进行工务署人员数据推送
        for (int i = 0; i < pushs.size(); i++) {

            push = pushs.get(i);

            // 判断数据状态是否是需要推送
            if (push.getPushDataWorker() == null || push.getPushDataWorker() == false) {
                continue;
            }

            gwsProjectCode = push.getGwsProjectCode();

            projectGuid = push.getProjectGuid();

            infoDTOs = gwsPeopleInfoDTOMapper.findByProjectGuidGetProple(projectGuid);

            // 循环将人员信息进行处理并且推送到工务署
            for (int j = 0; j < infoDTOs.size(); j++) {

                infoDTO = infoDTOs.get(j);

                idCode = new StringBuffer(infoDTO.getId_code());

                String headImagePathId = null;

                String issueCardPicId = null;

                String apiKey = push.getApiKey();

                // 根据身份证去查询该人员是否已经上传过头像照片，没有的话则进行上传并且存入数据库
                gwsPerson = gwsPersonMapper.selectOneRecordByIDCardNumber(idCode.toString());

                // 证明该人员的头像照片和打卡照片都不存在
                if (gwsPerson == null || gwsPerson.getHeadImagePathId() == null
                        || gwsPerson.getIssueCardPicId() == null) {
                    // 将身份证头像照片上传到工务署，并且将工务署返回的ID存入数据库
                    headImagePathId = gongWuSuUploadCWSService.imgDealWithAndSuffixGetHeadPathId(apiKey,
                            idCode.toString(), projectGuid, infoDTO.getId_photo());

                    if (StringUtils.isEmpty(headImagePathId)) {
                        failPeople.add(infoDTO.getId_code() + "人员信息推送工务署失败-失败原因:上传身份证头像图片失败");
                        continue;
                    }

                    // 将打卡照片上传工务署，并且将工务署返回的ID存入数据库
                    issueCardPicId = gongWuSuUploadCWSService.imgDealWithGetIssueCardPicId(apiKey, idCode.toString(),
                            projectGuid, infoDTO.getFacephoto());

                    if (StringUtils.isEmpty(issueCardPicId)) {
                        failPeople.add(infoDTO.getId_code() + "人员信息推送工务署失败-失败原因:上传打卡图片失败");
                        continue;
                    }
                }

                // 将图片在线地址替换成工务署返回的图片ID
                infoDTO.setId_photo(headImagePathId == null ? gwsPerson.getHeadImagePathId() : headImagePathId);
                infoDTO.setFacephoto(issueCardPicId == null ? gwsPerson.getIssueCardPicId() : issueCardPicId);

                infoDTO.setProject_ID(gwsProjectCode);

                JSONObject paramJson = JSONObject.parseObject(JSON.toJSONString(infoDTO));

                String timestamp = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");

                String resultInfo = innerFormalGWSCWRService.RegisterEmployee(paramJson, push.getApiSecret(),
                        push.getApiKey(), push.getApiVersion(), push.getClientSerial(), timestamp);

                if (resultInfo == null) {
                    log.error("获取结果时出错。跳过获取结果，继续上报下一条");
                    continue;
                }

                if ((innerFormalGWSCWRService.parseResultsCode(resultInfo).equals("00")
                        && innerFormalGWSCWRService.parseResultsMessage(resultInfo).equals("成功"))) {
                    log.info("本条数据推送成功" + infoDTO.getId_code());
                    // 成功数量加一
                    counter++;
                } else {
                    // 用来去除已上传好的人员
                    if (innerFormalGWSCWRService.parseResultsMessage(resultInfo).contains("此人员已经在此工程")) {
                        continue;
                    }
                    failPeople.add(infoDTO.getId_code() + "人员信息推送工务署失败-失败原因："
                            + innerFormalGWSCWRService.parseResultsMessage(resultInfo));
                    log.info(infoDTO.getId_code() + "人员信息推送工务署失败，原因："
                            + innerFormalGWSCWRService.parseResultsMessage(resultInfo));
                    continue;
                }
            }
        }

        JSONArray jsonArray = new JSONArray(failPeople);

        long timeSpent = System.currentTimeMillis() - beginTime;
        log.info("推送人员结束，本次推送耗时" + timeSpent + "---成功/总数：" + counter + "/" + infoDTOs.size());
        log.info("失败人员身份证" + jsonArray.toJSONString());
    }

    /**
     * 获取宇泛设备人员“考情”，定时推送到工务署去
     */
    @Async(value = "asyncExecutor")
    @Scheduled(fixedRate = 2 * 60 * 60 * 1000)
//    @Test
    public void updateAttendance() {

        log.info("宇泛设备直连，推送工务署人员开始..........");

        List<GwsYfRealNameSystemPush> pushs = realNameSystemPushMapper.findAll();

        System.out.println(pushs.size());

        // 用来存储单个实名制信息
        GwsYfRealNameSystemPush push = new GwsYfRealNameSystemPush();

        List<GwsAccessDeviceDTO> accessDeviceDTOs = new ArrayList<GwsAccessDeviceDTO>();

        GwsAccessDeviceDTO accessDeviceDTO = new GwsAccessDeviceDTO();

        JSONObject param = new JSONObject();

        List<JSONObject> passedlogs = new ArrayList<>();

        GwsAttendanceDTO attendanceDTO = new GwsAttendanceDTO();

        String gwsProjectCode = "";

        String projectGuid = "";

        int counter = 0;

        String apiKey = "";

        // 开始时间
        long beginTime = System.currentTimeMillis();

        String attImgPathInd = "";

        JSONArray fileArray = new JSONArray();

        for (int i = 0; i < pushs.size(); i++) {

            push = pushs.get(i);

            // 判断数据状态是否是需要推送
            if (push.getPushDataAtt() == null || !push.getPushDataAtt()) {
                continue;
            }

            projectGuid = push.getProjectGuid();

            gwsProjectCode = push.getGwsProjectCode();

            apiKey = push.getApiKey();

            innerFormalGWSCWRService.setApi_key(apiKey);
            innerFormalGWSCWRService.setApi_secret(push.getApiSecret());
            innerFormalGWSCWRService.setApi_version("1.0");
            innerFormalGWSCWRService.setClient_serial(push.getClientSerial());
            innerFormalGWSCWRService.setProject_ID(gwsProjectCode);

            accessDeviceDTOs = gwsAccessDeviceDTOMapper.findByProjectGuidGetAttendance(projectGuid);

            System.out.println(accessDeviceDTOs.size());

            for (int j = 0; j < accessDeviceDTOs.size(); j++) {
                try {
                    accessDeviceDTO = accessDeviceDTOs.get(j);


                    if(accessDeviceDTO.getStatus() == 1){
                        System.out.println("<<<<<<<<<<<<<<<<<<------------------已经上传了---------------------------------->>>>>>>>>>>>");
                        continue;
                    }


                    // 将工务署编号插入进入
                    param.put("Project_ID", gwsProjectCode);
                    param.put("Device_ID", accessDeviceDTO.getDevice_id());

                    attImgPathInd = gongWuSuUploadCWSService.imgDealWithGetAttImgId(apiKey,
                            accessDeviceDTO.getPerson_id(), accessDeviceDTO.getPassed_time(), gwsProjectCode, projectGuid,
                            accessDeviceDTO.getSite_photo());

                    if (StringUtils.isEmpty(attImgPathInd)) {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("name", accessDeviceDTO.getPerson_name());
                        jsonObject.put("msg", "图片上传失败");
                        jsonObject.put("idCard", accessDeviceDTO.getPerson_id());
                        fileArray.add(jsonObject);
                        continue;
                    }

                    accessDeviceDTO.setSite_photo(attImgPathInd);

                    JSONObject paramJson = JSON.parseObject(JSON.toJSONString(accessDeviceDTO));

                    System.out.println("输出的值为----------------------------->>>>>>>>>>>>>>>>");
                    System.out.println(paramJson);

                    //因为数据格式需要list格式
                    passedlogs.add(paramJson);

                    param.put("passedlog_list", passedlogs);

                    String resultInfo = innerFormalGWSCWRService.UploadPassedLog(param);

                    System.out.println("上传输出的值为------------------------------->>>>>"+resultInfo+"+++++++++++++++++++++++++++++++++++");

                    String code = innerFormalGWSCWRService.parseResultsCode(resultInfo);

                    String msg = innerFormalGWSCWRService.parseResultsMessage(resultInfo);

                    if (!"00".equals(code)) {
                        System.out.println("进入了----------------------->>>>>>>>>>.失败了");
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("name", accessDeviceDTO.getPerson_name());
                        jsonObject.put("msg", msg);
                        jsonObject.put("idCard", accessDeviceDTO.getPerson_id());
                        fileArray.add(jsonObject);
                        continue;
                    }

                    int i1 = gwsAccessDeviceDTOMapper.updateStatus(accessDeviceDTO.getShowTime());
                    System.out.println("<<<<<<<<<<<<---------------------修改成功------------------------->>>>>>>>>>"+i1);
                    counter++;

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        long timeSpent = System.currentTimeMillis() - beginTime;
        log.error("推送失败的人员信息" + fileArray.toJSONString());
        log.info("推送考情结束，本次推送耗时" + timeSpent + "---成功/总数：" + counter + "/" + accessDeviceDTOs.size());
    }

    @Async(value = "asyncExecutor")
    @Scheduled(fixedRate = 1000 * 60 * 60)
    public void updatePeople() {

        // 将所有宇泛数据推送到工务署的项目查询出来
        List<GwsYfRealNameSystemPush> pushs = realNameSystemPushMapper.findAll();

        // openapi2项目中接口 用于获取宇泛人员新增并且返回差值
        String url = "http://openapi2.yishun618.com/realName/updateDbAndReturnTrm";

        for (GwsYfRealNameSystemPush gwsYfRealNameSystemPush : pushs) {

            String projectGuid = gwsYfRealNameSystemPush.getProjectGuid();

            String projectId = gwsYfRealNameSystemPush.getGwsProjectCode();

            JSONObject paramJson = new JSONObject();

            List<String> failIdCode = new ArrayList<String>();

            List<String> successIdCode = new ArrayList<String>();

            paramJson.put("projectGuid", projectGuid);

            String res = HttpUtil.post(url, paramJson.toJSONString());

            res = res.replace("[", "").replace("]", "").replace("\"", "");
            // String[] ids = res.split(",");
            String[] ids = {"522228197411140618", "513524197608047097", "532130198302211328", "522129197410073039",
                    "452428179604162023", "52242719900723324", "513433198706240216", "500238198404140873"};

            List<JSONObject> userLeaveProject_list = new ArrayList<JSONObject>();

            LocalDateTime dateTime = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String exit_time = formatter.format(dateTime);

            // 清楚前面JSON进行二次利用
            paramJson.remove("projectGuid");

            // 装载参数
            CWRService.setApi_key(gwsYfRealNameSystemPush.getApiKey());
            CWRService.setApi_secret(gwsYfRealNameSystemPush.getApiSecret());
            CWRService.setClient_serial(gwsYfRealNameSystemPush.getClientSerial());
            paramJson.put("Project_ID", projectId);
            for (int j = 0; j < ids.length; j++) {

                JSONObject object = new JSONObject();
                object.put("id_code", ids[j]);
                object.put("exit_time", exit_time);
                userLeaveProject_list.add(object);

                paramJson.put("userLeaveProject_list", userLeaveProject_list);

                // 将宇泛与数据库查询出来的差值进行人员退场处理
                JSONObject gwsRes = CWRService.userLeaveProject(paramJson);

                userLeaveProject_list.remove(0);
                paramJson.remove("userLeaveProject_list");

                // 退场成功或者人员不存在工务署中一律在数据库中删除
                if (("true").equals(gwsRes.getString("result")) || ("03").equals(gwsRes.getString("code"))) {
                    successIdCode.add(ids[j]);
                    continue;
                }
                // 将成功的人数在数据库进行删除
                failIdCode.add(ids[j]);
            }

            yfPeopleInfoMapper.delNotInIdCode(projectGuid, successIdCode);

            log.info("退场人数(总数/成功-不存在):" + ids.length + "/" + successIdCode.size());
        }
    }
}